#pragma once
#include<iostream>
#include<vector>
#include "Mutex.hpp"
#include "Sem.hpp"


using namespace MuteModule;
using namespace SemModule;

const int NUM = 5;
template <typename T>
class RingQueue
{
public:
    RingQueue(int num = NUM)
    :_cap(num),
     _rq(num),
     _blank_sem(num),
     _p_step(0),
     _data_sem(0),
     _c_step(0)
    {

    }
    void Equeue(T& in)
    {
        //生产者
        _blank_sem.P();//先申请信号量,占上资源在获取锁也可以
        LockGuard t(_pmutex);
        _rq[_p_step++] = in;
        _p_step %= NUM;
        _data_sem.V();
    }
    void Pop(T& out)
    {
        _data_sem.P();
        LockGuard t(_cmutex);
        out = _rq[_c_step++];
        _c_step %= NUM;
        _blank_sem.V();
    }

    ~RingQueue()
    {

    }
private:
    std::vector<T> _rq;
    int _cap;
    //生产者
    Sem _blank_sem;//空位置
    int _p_step;

    Sem _data_sem;//数据
    int _c_step;

    Mutex _cmutex;//客户锁
    Mutex _pmutex;//消费者锁
};

